package com.apes.hr.transfer.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.generator.service.SequenceService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.jpa.spec.model.Group;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.outbox.OutboxSubscriberService;
import com.apes.framework.query.SqlService;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.EventUtil;
import com.apes.framework.util.MapUtil;
import com.apes.hr.base.model.Employee;
import com.apes.hr.base.model.Staffing;
import com.apes.hr.base.model.TransferRecord;
import com.apes.hr.base.model.WorkPost;
import com.apes.hr.base.repository.EmployeeRepository;
import com.apes.hr.base.repository.StaffingRepository;
import com.apes.hr.base.repository.TransferRecordRepository;
import com.apes.hr.base.repository.WorkPostRepository;
import com.apes.hr.base.service.EmployeeService;
import com.apes.hr.base.service.StaffingService;
import com.apes.hr.group.service.DingDingDeptRelevanceService;
import com.apes.hr.group.service.DingDingDeptService;
import com.apes.hr.paySupport.service.SupportApplicationAffirmService;
import com.apes.hr.recruit.model.RecruitOrder;
import com.apes.hr.recruit.repository.RecruitOrderRepository;
import com.apes.hr.thirdParty.dingidng.model.DingDingToken;
import com.apes.hr.thirdParty.dingidng.service.DingDingService;
import com.apes.hr.transfer.model.TransferApplication;
import com.apes.hr.transfer.model.TransferApplicationExecution;
import com.apes.hr.transfer.model.TransferApplicationItem;
import com.apes.hr.transfer.model.TransferApplicationRole;
import com.apes.hr.transfer.repository.*;
import com.apes.scm.masterdata.enumeration.model.Enumeration;
import com.apes.scm.masterdata.enumeration.repository.EnumerationRepository;
import com.apes.scm.masterdata.frame.model.Branch;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.repository.BranchRepository;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.party.model.AccessProvider;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.party.repository.AccessProviderRepository;
import com.apes.scm.masterdata.party.repository.PartyRepository;
import com.apes.scm.masterdata.party.repository.PartyRoleRepository;
import com.apes.scm.masterdata.party.service.PartyRoleService;
import com.apes.scm.masterdata.party.service.PartyService;
import com.apes.scm.rbac.model.Post;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.LocalPermitItemRepository;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import com.apes.scm.rbac.service.PostService;
import com.apes.scm.rbac.service.UserService;
import org.apache.commons.lang.time.DateUtils;
import org.bson.Document;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 功能：调动申请
 *
 * @author Fengjiajing
 * @create 2018-07-05 10:07
 */
@Service("hrTransferApplicationService")
public class TransferApplicationService  extends DomainService {
    @Autowired
    SqlService sqlService;
    @Autowired
    public TransferApplicationRepository transferApplicationRepository;
    @Autowired
    public TransferApplicationItemService itemService;
    @Autowired
    public TransferApplicationRoleRepository roleRepository;
    @Autowired
    public SequenceService sequenceService;
    @Autowired
    public TransferApplicationExecutionRepository executionRepository;
    @Autowired
    public EmployeeRepository employeeRepository;
    @Autowired
    PartyRepository partyRepository;
    @Autowired
    public StaffingRepository staffingRepository;
    @Autowired
    public StaffingService staffingService;
    @Autowired
    public UserService userService;
    @Autowired
    PostRepository postRepository;
    @Autowired
    PartyService partyService;
    @Autowired
    PartyRoleService partyRoleService;
    @Autowired
    EmployeeService employeeService;
    @Autowired
    RecruitOrderRepository recruitOrderRepository;
    @Autowired
    TransferApplicationItemRepository transferApplicationItemRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    TransferRecordRepository transferRecordRepository;
    @Autowired
    EnumerationRepository enumerationRepository;
    @Autowired
    QuitJobOrderRepository quitJobOrderRepository;
    @Autowired
    PartyRoleRepository partyRoleRepository;
    @Autowired
    DingDingToken dingDingToken;
    @Autowired
    DingDingService dingService;
    @Autowired
    LocalPermitItemRepository localPermitItemRepository;
    @Autowired
    BranchRepository branchRepository;
    @Autowired
    WorkPostRepository workPostRepository;
    @Autowired
    DingDingDeptRelevanceService dingDingDeptRelevanceService;
    @Autowired
    DingDingDeptService dingDingDeptService;
    @Autowired
    private AccessProviderRepository accessProviderRepository;
    @Autowired
    private DeptRepository deptRepository;
    @Autowired
    private SupportApplicationAffirmService supportApplicationAffirmService;
    @Autowired
    private MongoTemplate mongoTemplate;


    public Map getCompanyByBranch(SimpleRequest request){
        String branchId = (String) JpaDsl.getGroup(request).getGroups().get(0).getFilters().get(0).getValue();
        List<Dept> byBranch = deptRepository.findByBranchId(branchId);
        List<PartyRole> result = new ArrayList<>();
        byBranch.stream().forEach(item -> {
            result.add(item.getCompany());
        });
        return MapUtil.mapper(
                "content", result,
                "total", result.size(),
                "size", result.size()
        );
    }

    public Map getCompanyByBranchId(SimpleRequest request){
        String branchId = request.get("branchId");
        List<Dept> byBranch = deptRepository.findByBranchId(branchId);
        List<PartyRole> result = new ArrayList<>();
        byBranch.stream().forEach(item -> {
            result.add(item.getCompany());
        });
        return MapUtil.mapper(
                "content", result,
                "total", result.size(),
                "size", result.size()
        );
    }

    public TransferApplication save(SimpleRequest request) {



        TransferApplication transferApplication = request.getO(TransferApplication.class);
        transferApplication.setState("create");  //设置当前的状态
        Post post = postRepository.findOne(request.getPostId());

        transferApplication.setDept(post.getDept());

        transferApplication.setCompany(post.getCompany());
        checkDate(transferApplication);
        checkAccessProvider(transferApplication.getTransferApplicationItems());
        if(transferApplication.getHrTransferType() == enumerationRepository.findOne("000102")){
            checkQuitJob(transferApplication);
        }
        checkTransferApplicationRole(transferApplication);
        if(transferApplication.getCreateDate() == null) {
            transferApplication.setCreateDate(new Date());
        }else {
            transferApplication.setUpdateDate(new Date());
        }
        Set<TransferApplicationItem> items = transferApplication.getTransferApplicationItems();
        items.forEach(item -> {
            if(item.getId()!= null){
                int id = item.getId();
                List<TransferApplicationItem> yItem  = itemService.findById(id);
                if(yItem.size()>0){
                    itemService.delete(yItem);
                }
            }

        });
        return transferApplicationRepository.saveAndFlush(transferApplication);
    }

    /**
     * 检查调动前和调动后的公司接入商是否一致
     */
    private void checkAccessProvider(Set<TransferApplicationItem> items){
        items.forEach(item -> {
            if(item.getTransferApplications().getHrTransferType().getId().equals("000102")){
                AccessProvider ago = accessProviderRepository.findByCompany(item.getTransferUid().getCompany().getId());
                List<Dept> depts = deptRepository.findByBranch(item.getBranchAfter());
                if(!depts.isEmpty()){
                    AccessProvider later = accessProviderRepository.findByCompany(deptRepository.findByBranch(item.getBranchAfter()).get(0).getCompany().getId());
                    if(!ago.getId().equals(later.getId())){
                        throw new RuntimeException(item.getTransferUid().getName()+"调动前后接入商不同不允许做调动单");
                    }
                }
            }
        });
    }

    private void checkQuitJob(TransferApplication transferApplication) {
        Set<TransferApplicationItem> items = transferApplication.getTransferApplicationItems();
        items.forEach(item -> {
            if (!quitJobOrderRepository.findByEmployeeAndState(item.getTransferUid()).isEmpty()){
                throw new RuntimeException(item.getTransferUid().getName()+"有离职单未完成!不允许调动!");
            };
        });
    }

    /**
     * 创建日期最大的明细
     * @param list
     * @return
     */
    private int selectLastOne(List<TransferApplicationItem> list) {
        int index = 0;
        Long dates[] = new Long[list.size()];
        for (int i = 1; i <= list.size(); i++) {
            // 把date类型的时间对象转换为long类型，时间越往后，long的值就越大，
            // 所以就依靠这个原理来判断距离现在最近的时间
            dates[i - 1] = list.get(i-1).getCreateDate().getTime();
        }

        Long maxIndex = dates[0];// 定义最大值为该数组的第一个数
        for (int j = 0; j < dates.length; j++) {
            if (maxIndex < dates[j]) {
                maxIndex = dates[j];
                // 找到了这个j
                index = j;
            }
        }
        return index;
    }

    private void checkTransferApplicationRole(TransferApplication transferApplication){
        Set<TransferApplicationItem> items = transferApplication.getTransferApplicationItems();
        items.forEach(item ->{
            Set<TransferApplicationRole> transferApplicationRoleSet = item.getTransferApplicationRoles();
            if (transferApplicationRoleSet.isEmpty()) throw new RuntimeException(item.getTransferUid().getName()+"本地角色不能为空。");
            if (transferApplicationRoleIsRepeat(transferApplicationRoleSet,item))throw new RuntimeException(item.getTransferUid().getName()+"本地角色重复。");
                //调动单
            if(transferApplication.getHrTransferType().getId().equals("000102")){
                item.setEffectiveDate(DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 06:00:00",DateUtil.SHOW_DATETIME_FORMAT));
            }else {
                //支援单
                //开始时间为上午 6:00 为下午12:00 结束时间为上午 12:00 下午为23:59:59
                if (item.getEffectiveTime().getCode().equals("AM")){
                    item.setEffectiveDate(DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 06:00:00",DateUtil.SHOW_DATETIME_FORMAT));
                }
                if (item.getEffectiveTime().getCode().equals("PM")){
                    item.setEffectiveDate(DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
                }
                if (item.getEndTime().getCode().equals("AM")){
                    item.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
                }
                if (item.getEndTime().getCode().equals("PM")){
                    item.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 23:59:59",DateUtil.SHOW_DATETIME_FORMAT));
                }
            }
        });

    }


    /**
     * 检查set集合里的对象是否有重复的
     * @param orderList
     * @param item
     * @return
     */
    private Boolean transferApplicationRoleIsRepeat(Set<TransferApplicationRole> orderList,TransferApplicationItem item) {
        Set<TransferApplicationRole> set = new TreeSet<TransferApplicationRole>(new Comparator<TransferApplicationRole>() {
            public int compare(TransferApplicationRole a, TransferApplicationRole b) {
                if (a.getPostId()==null || b.getPostId()==null) throw new RuntimeException(item.getTransferUid().getName()+"有本地角色为空，请检查。");
                // 字符串则按照asicc码升序排列
                return a.getPostId().compareTo(b.getPostId());
            }
        });
        set.addAll(orderList);
        if (set.size() < orderList.size()) {
            return true;
        }
        return false;
    }

    /** 创建时的检查规则 */
    public void checkDate(TransferApplication transferApplication){
        Enumeration hrTransferType = transferApplication.getHrTransferType();
        String sType = hrTransferType.getId();
        Set<TransferApplicationItem> items = transferApplication.getTransferApplicationItems();
        items.forEach(item -> {

            List<TransferApplicationItem>  timeOutItems = transferApplicationItemRepository.findByTransferUidAndIconExecuteAndEffectiveDate(item.getTransferUid(),true,item.getEffectiveDate());
            if (!timeOutItems.isEmpty()){
                timeOutItems.forEach(timeOutItem->{
                    if (timeOutItem.getTransferApplications().getHrTransferType().equals("000102")){
                        throw new RuntimeException(item.getTransferUid().getName() +"与调动申请单：" + timeOutItems.get(timeOutItems.size()-1).getTransferApplications().getId() + "冲突");
                    }
                });
            }

            //未执行且未废除的调动 支援单
            List<TransferApplicationItem>  Items = transferApplicationItemRepository.findByTransferUidAndIconExecute(item.getTransferUid(),false);
            List<TransferApplicationItem>  itemList= new ArrayList<>();
            if (!Items.isEmpty()){
                Items.forEach(Item->{
                    String state= Item.getTransferApplications().getState();
                    if (!(state.equals("repeal")||state.equals("delete")||Item.getId().equals(item.getId()))&&!Item.isRepeal()){
                        itemList.add(Item);
                    }
                });
            }

            //执行还未结束支援的支援单
            List<TransferApplicationItem> supItemList =  transferApplicationItemRepository.findByTransferUidAndIconExecute(item.getTransferUid(),true);
            if(!supItemList.isEmpty()){
                supItemList.forEach(supItem->{
                    if (supItem.getTransferApplications().getHrTransferType().getId().equals("000103")
                            && !supItem.getHrTransferKind().getId().equals("000430") //不等于临时调工号
                            && supItem.getEndDate().getTime() > new Date().getTime()
                            && supItem.getTransferUid().equals(item.getTransferUid())
                            &&( !supItem.getTransferApplications().getState().equals("repeal")
                            || !supItem.getTransferApplications().getState().equals("delete"))
                            &&!supItem.isRepeal()){
                        itemList.add(supItem);
                    }
                });


            }
            if (!itemList.isEmpty()){
                TransferApplicationItem oldItem = itemList.get(selectLastOne(itemList));
                String oldType =oldItem.getTransferApplications().getHrTransferType().getId();
                if (oldType.equals("000103")&sType.equals("000102")){//旧单为支援单 且新单为调动单
                    //新单的生效日期小于等于旧单的生效日期 提示
                    if(item.getEffectiveDate().getTime()<= oldItem.getEffectiveDate().getTime()){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！支援前不可调动！");
                        //新单的生效日期大于旧单的生效日期 && 新单的生效日期 小于等于 旧单支援结束日期
                    } else if (item.getEffectiveDate().getTime() >oldItem.getEffectiveDate().getTime()
                            & item.getEffectiveDate().getTime()<= oldItem.getEndDate().getTime() ){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！不可在支援期间调动！");
                    }
                }else if (oldType.equals("000103")&sType.equals("000103")){//旧单为支援单 且新单为支援单
                    //新单的生效日期小于等于旧单的生效日期 && 新单的结束支援日期 大于 旧单生效日期 提示
                    if(item.getEffectiveDate().getTime()<= oldItem.getEffectiveDate().getTime()
                            && item.getEndDate().getTime()> oldItem.getEffectiveDate().getTime()){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！支援前不可支援！");
                        //新单的生效日期大于旧单的生效日期 && 新单的生效日期 小于等于 旧单支援结束日期
                    } else if (item.getEffectiveDate().getTime() >oldItem.getEffectiveDate().getTime()
                            &&item.getEffectiveDate().getTime()<= oldItem.getEndDate().getTime() ){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！不可在支援期间支援！");
                        //新单的生效日期小于旧单的生效日期 && 新单的支援结束日期 大于 旧单支援结束日期
                    } else if (item.getEffectiveDate().getTime() < oldItem.getEffectiveDate().getTime()
                            &&item.getEndDate().getTime() > oldItem.getEndDate().getTime() ){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！不可在支援期间支援！");
                        //新单的生效日期小于等于旧单的生效日期 && 新单的结束支援日期大于等于旧单的生效日期
                    }else if (item.getEffectiveDate().getTime() <= oldItem.getEffectiveDate().getTime()
                            && item.getEndDate().getTime() >= oldItem.getEffectiveDate().getTime()){
                        throw new RuntimeException(item.getTransferUid().getName() +"与支援申请单：" + oldItem.getTransferApplications().getId() + "冲突！");
                        //新单的生效日期小于旧单的结束支援日期
                    }else if(item.getEffectiveDate().getTime() < oldItem.getEffectiveDate().getTime()){
                        SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd" );
                        Date effectiveDate = null;
                        Date oldEffectiveDate = null;
                        try {
                            effectiveDate = sdf.parse(sdf.format(item.getEffectiveDate()));
                            oldEffectiveDate = sdf.parse(sdf.format(oldItem.getEffectiveDate()));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        //新单的生效日期小于旧单的生效日期 && 新单的生效日期
                        if (!(effectiveDate.getTime() < oldEffectiveDate.getTime() && item.getEndDate().getTime() < oldItem.getEffectiveDate().getTime())){
                            throw new RuntimeException("人员名称：" + item.getTransferUid().getName() + "支援单的开始时间和结束时间存在已审核的单据，请勿重复制单，单据号码：" + oldItem.getTransferApplications().getId());
                        }
                    }
                } else if (oldType.equals("000102")&sType.equals("000102")){//旧单为调动单 且新单为调动单
                    //新单的生效日期小于等于旧单的生效日期 提示
                    if(item.getEffectiveDate().getTime()<= oldItem.getEffectiveDate().getTime()){
                        if(item.getBranch()!=item.getBranchAfter()|| item.getWorkPost() != item.getWorkPostAfter()){
                            throw new RuntimeException(item.getTransferUid().getName() +"与调动申请单：" + oldItem.getTransferApplications().getId() + "冲突");
                        }
                    }else if(item.getEffectiveDate().getTime() > oldItem.getEffectiveDate().getTime()
                            &new Date().getTime() < oldItem.getEffectiveDate().getTime()) {
                        //新单的生效日期大于旧单的生效日期 & 新单的创建日期 小于 旧单的生效日期
                        throw new RuntimeException(item.getTransferUid().getName() +"与调动申请单：" + oldItem.getTransferApplications().getId() + "冲突");
                    }
                } else if (oldType.equals("000102")&sType.equals("000103")){//旧单为调动单 且新单为支援单
                    //新单的生效日期小于等于旧单的生效日期 && 新单的支援结束日期 大于等于 旧单生效日期
                    if (item.getEffectiveDate().getTime() <= oldItem.getEffectiveDate().getTime()&&
                            item.getEndDate().getTime() >= oldItem.getEffectiveDate().getTime()){
                        throw new RuntimeException( item.getTransferUid().getName() +"与调动申请单：" + oldItem.getTransferApplications().getId() + "冲突");
                        //新单的生效日期大于等于旧单的生效日期 && 新单的支援结束日期 大于旧单生效日期
                    }else if (item.getEffectiveDate().getTime() >= oldItem.getEffectiveDate().getTime()&&
                            item.getEndDate().getTime() > oldItem.getEffectiveDate().getTime()){
                        item.setBranch(oldItem.getBranchAfter());
                        item.setWorkPost(oldItem.getWorkPostAfter());
                        item.setJob(oldItem.getJobAfter());
                        item.setRankId(oldItem.getRankIdAfter());
                    }
                }
            }
        });

    }

    public TransferApplication update(SimpleRequest request) throws RuntimeException {
        String id = request.get("id");
        TransferApplication transferApplication =  transferApplicationRepository.findOne(id);
        checkTransferApplicationRole(transferApplication);
        if (transferApplication == null) throw new RuntimeException("调动申请单【" + id + "】在系统中不存在。");
        return save(request);
    }

    /**
     * 功能：删除
     * @param request
     */
    public String delete(SimpleRequest request) {
        String id = request.get("id");
        TransferApplication transferApplication = transferApplicationRepository.findOne(id);
        if (transferApplication == null) throw new RuntimeException("调动申请单：" + id + " 在系统中不存在。");
        transferApplication.setState("delete");
        transferApplication.setDeleteDate(new Date());
        transferApplicationRepository.saveAndFlush(transferApplication);
        return "删除成功！";
    }

    /**
     * 发文
     * @param request
     * @return
     * @throws RuntimeException
     */
    public TransferApplication sendOut(SimpleRequest request) throws RuntimeException {
        String id = request.get("id");
        TransferApplication oldTransferApplication =  transferApplicationRepository.findOne(id);
        if (oldTransferApplication == null) throw new RuntimeException("调动申请单【" + id + "】在系统中不存在。");
        TransferApplication transferApplication = request.getO(TransferApplication.class);
        checkTransferApplicationRole(transferApplication);
        transferApplication.setState("sendOut");
        transferApplication.setSendOutDate(new Date());
        transferApplication.setSendOutUid(this.getPerson(request));
        return transferApplicationRepository.saveAndFlush(transferApplication);
    }
    /**
     * 功能：查找 所有
     * @param request
     * @return
     */
    public Page<TransferApplication> findAll(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        filters.forEach(item -> {
            if(item.get("field").equals("hrTransferType")){
                item.put("field","hrTransferType.id");
            }
        });
        JSONObject djzt = new JSONObject();
        djzt.put("field","state");
        djzt.put("operator","NE");
        djzt.put("value","delete");
        filters.add(djzt);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return transferApplicationRepository.findAll(JpaDsl.toCriteria(filters),PageRequest.of(request.get("page"), request.get("size"),sort));
    }
    /**
     * 功能：查找 调动 单使用
     * @param request
     * @return
     */
    public Page<TransferApplication> findTransferApplication(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        JSONObject dj = new JSONObject();
        dj.put("field","hrTransferType.id");
        dj.put("operator","EQ");
        dj.put("value","000102");
        filters.add(dj);
        JSONObject djzt = new JSONObject();
        djzt.put("field","state");
        djzt.put("operator","NE");
        djzt.put("value","delete");

        filters.add(djzt);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return transferApplicationRepository.findAll(JpaDsl.toCriteria(filters),PageRequest.of(request.get("page"), request.get("size"),sort));
    }
    /**
     * 功能：查找 支援单使用
     * @param request
     * @return
     */
    public Page<TransferApplication> findSupportApplication(SimpleRequest request) {
        List<Map> filters = request.get("condition");
        Post post = postRepository.findOne(request.getPostId());
        PartyRole company = post.getCompany();
        JSONObject dj = new JSONObject();
        dj.put("field","hrTransferType.id");
        dj.put("operator","EQ");
        dj.put("value","000103");
        filters.add(dj);
        JSONObject djzt = new JSONObject();
        djzt.put("field","state");
        djzt.put("operator","NE");
        djzt.put("value","delete");
        filters.add(djzt);
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return transferApplicationRepository.findAll(JpaDsl.toCriteria(filters),PageRequest.of(request.get("page"), request.get("size"),sort));
    }


    /**
     * 功能：查找单独订单使用
     * @param request
     * @return
     */
    public TransferApplication findOne(SimpleRequest request) throws RuntimeException {
        String id = request.get("id");
        TransferApplication transferApplication = transferApplicationRepository.findOne(id);
        if(transferApplication == null) throw new RuntimeException("调动计划单：" + id + " 在系统中不存在。");
        String state = transferApplication.getState();
        if(!state.equals("delete")){
            return transferApplication;
        }else {
            throw new RuntimeException("调动计划单：" + id + " 已删除。");
        }
    }

    /**
     * 功能：下拉模糊查询使用
     * @param request
     * @return
     */
    public Page<Employee> findPartyEmployee(SimpleRequest request) {
        String key = request.get("key");
//        Post post = postRepository.findOne(request.getPostId());
        List<PartyRole> roleList = new ArrayList<>();
        List<String> orgIds = SpringManager.getBean(PostService.class).findLocalPermitItems(request.getPostId(), "pp_search", "pt_company");
        if(orgIds.isEmpty()) roleList.addAll(partyRoleRepository.findAllCompany());
        orgIds.forEach(s -> roleList.add(partyRoleRepository.findOne(s)));
//        Branch branch =post.getBranch();
//        if (branch.getBranchType().getId().equals("000007")){
//            return employeeRepository.findByEmployeeState(key,"000088",roleList,branch, PageRequest.of(request.get("page"), request.get("size")));
//        } else {
        return employeeRepository.findByEmployeeState2(key,"000088",roleList,PageRequest.of(request.get("page"), request.get("size")));
//        }

    }

    /**
     * 功能：审批
     * @param request
     */
    public TransferApplication done(SimpleRequest request) throws RuntimeException {
        TransferApplication transfer = request.getO(TransferApplication.class);
        //执行内容
        List<TransferApplicationExecution> listExec = new ArrayList();
        Set<TransferApplicationItem> items = transfer.getTransferApplicationItems();
        Enumeration hrTransferType = transfer.getHrTransferType();
        String sType = hrTransferType.getId();
        // 当天日期
        Date dToday = new Date();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String sToday = formatter.format(dToday);
        AtomicReference<Boolean> isCarbonCopy = new AtomicReference<>(false);

        //判断当前时间是上午还是下午 结果为“0”是上午 结果为“1”是下午
        GregorianCalendar ca = new GregorianCalendar();
        int a = ca.get(GregorianCalendar.AM_PM);
        String time = a == 0 ? "AM" :"PM";

        items.forEach(item -> {

            //实际支援天数  = 具体上下午计算 思路源自钉钉
            if ("000103".equals(transfer.getHrTransferType().getId())){
                Double day = supportApplicationAffirmService.
                        calculateDay((item.getEndDate().getTime() - item.getEffectiveDate().getTime()) / (1000L * 3600L * 24L) - 1,
                                item.getEffectiveTime().getCode(), item.getEndTime().getCode());
                item.setActualSupportDays(String.valueOf(day));
            }

            Date dDate = item.getEffectiveDate();   //生效日期
            String sDate = formatter.format(dDate);

            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date dTodayTwo = null;
            Date dDateTwo = null;
            int i = 0;
            try {
                dTodayTwo = dateFormat.parse(sToday);
                dDateTwo = dateFormat.parse(sDate);
                i = dTodayTwo.compareTo(dDateTwo);//如果当天日期大于生效日期，则返回一个大于 0 的值。
            } catch (ParseException e) {
                e.printStackTrace();
            }

            if (i>0 && sType.equals("000102")) {
                isCarbonCopy.set(true);
            }
//            item.setIconExecute(true);
            if(!sToday.equals(sDate)||sType.equals("000103")){ // 非当天 或者 调动类型(000102:hrTT_01调动; 000103:hrTT_02支援) 为 支援 的 生成执行表
                insertExecution(item,hrTransferType);// 支援的须写入执行表执行支援结束内容 但不对 编制 做修改
            }
            User user = userRepository.findByOrigin(item.getTransferUid().getOrigin());
            if (user!=null){
                // 更新要备份 的 原 item 角色 列表
                List<Post> postLists = user.getPosts();
                if (postLists.size()>0) {
                    List<Post> posts = new ArrayList<>();
                    StringBuffer yRoleList = new StringBuffer();
                    postLists.forEach(yRole -> {
                        yRoleList.append(yRole.getId()+";");
                    });
                    transferApplicationItemRepository.updateItemRoles(yRoleList.toString(),item.getId().toString());
                }
            }
            if(!sToday.equals(sDate)){//如果不是今天的明细内容 执行标识为否
                item.setIconExecute(false);
                return;
            }

            if(sType.equals("000103")){ //支援类型 判断是否今天的明细 具体到上下午
                //如果开始日期是今天的，但开始时间不符的，执行标识为否
                if (sToday.equals(sDate) && !item.getEffectiveTime().getCode().equals(time)){
                    item.setIconExecute(false);
                    return;
                }
            }

            if (!item.isRepeal()){
                TransferApplicationExecution iExec = new TransferApplicationExecution();
                iExec.setHrTransferType(transfer.getHrTransferType());
                iExec.setTransferApplicationItems(item);
                iExec.setEffectiveDate(item.getEffectiveDate());
                iExec.setEndDate(item.getEndDate());
                iExec.setEffectiveDate(item.getEffectiveDate());
                iExec.setTransferUid(item.getTransferUid());
                iExec.setBranch(item.getBranchAfter());
                iExec.setJob(item.getJobAfter());
                iExec.setRankId(item.getRankIdAfter());
                iExec.setOnDutyState(item.getOnDutyStateAfter());
                iExec.setStaffShare(item.getStaffShareAfter());
                iExec.setWorkPost(item.getWorkPostAfter());
                listExec.add(iExec);
            }
        });

        if(listExec.size()>0)updateRYXX(listExec,false);//参数 :更新列表，是否扣减待调人数：不扣
        //执行内容 END
        transfer.setState("done");
        transfer.setApproveDate(new Date());
        if (isCarbonCopy.get()){
            com.apes.framework.plugin.workflow.parser.model.User user = new com.apes.framework.plugin.workflow.parser.model.User();
            Branch branch = branchRepository.findOne(request.getBranchId());
            WorkPost workPost = workPostRepository.findOne("0000252");
            List<Map> mapList = user.getUsersRecursiveByWorkPost(branch,workPost);
            mapList.addAll(user.getUsersRecursiveByWorkPost(branch,workPostRepository.findOne("0000062")));
            mapList.addAll(user.getUsersRecursiveByWorkPost(branch,workPostRepository.findOne("0000080")));
            mapList = mapList.stream().distinct().collect(Collectors.toList());
            JSONArray toArray = JSONArray.parseArray(JSON.toJSONString(mapList));
            sendSynEvent("event:wf.carbonCopy", mapper(
                    "sourceBusinessType", transfer.getInnerBusinessType(),
                    "sourceBusinessKey",transfer.getInnerBusinessKey(),
                    "operate", "yyadmin",
                    "content", "支援/调动单过期审核提醒。",
                    "from_id", request.getPersonId(),
                    "to_id", toArray,
                    "processDefinitionName", "支援/调动单",
                    "formId", sType.equals("000103")?"/form/hr.supportApplication":"/form/hr.transferApplication",
                    "api", "hr.transferApplication.findOne",
                    "checked", false
            ));
        }
        checkTransferApplicationRole(transfer);
        return transferApplicationRepository.saveAndFlush(transfer);
    }

    /**
     * 废除 调动 支援单
     * @param request
     * @return
     * @throws RuntimeException
     */
    public TransferApplication repeal(SimpleRequest request) throws RuntimeException {
        TransferApplication transfer = request.getO(TransferApplication.class);
        // 将之前就已经终止的单查出来
        TransferApplication oldTransfer = transferApplicationRepository.findOne(transfer.getId());
        List<Integer> oldItems = new ArrayList<>();
        oldTransfer.getTransferApplicationItems().forEach(item -> {
            if (item.isRepeal()){
                oldItems.add(item.getId());
            }
        });

        List<TransferApplicationExecution> listExec = new ArrayList();// 废除 调动 列表
        List<TransferApplicationExecution> listEndExec = new ArrayList(); // 废除 支援列表
        Set<TransferApplicationItem> items = transfer.getTransferApplicationItems();
//        transfer.setState("repeal");
        Enumeration hrTransferType = transfer.getHrTransferType();
        String sType = hrTransferType.getId();//类型(000102:hrTT_01调动; 000103:hrTT_02支援)
        items.forEach(item -> {

            if (!oldItems.contains(item.getId())){
                Date dDate = new Date();

                SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
                Date dToday= formatter.parse(formatter.format(dDate),new ParsePosition(0));
                Date startDate = item.getEffectiveDate();
                Date endDate = item.getEndDate();
                if (item.isRepeal()){
                    if (item.getRepealDate()== null)throw new RuntimeException("实际最后支援/调动日不予许为空。");
                    if(item.getRepealCause()== null)throw new RuntimeException("终止原因不予许为空。");

                    if ("000103".equals(transfer.getHrTransferType().getId())){
                        if (item.getRepealTime()== null)throw new RuntimeException("实际最后支援时间不允许为空");
                        //实际支援天数=实际最后支援时间-开始时间+1
                        Double day = supportApplicationAffirmService.
                                calculateDay((item.getRepealDate().getTime() - item.getEffectiveDate().getTime()) / (1000L * 3600L * 24L) - 1,
                                        item.getEffectiveTime().getCode(), item.getRepealTime().getCode());
                        item.setActualSupportDays(String.valueOf(day));
                    }
                    //                transferApplicationItemRepository.save(item);
                    // 执行内容
                    TransferApplicationExecution iExec ;
                    if (sType.equals("000102")){
                        iExec = new TransferApplicationExecution();
                    } else {
                        iExec = executionRepository.findByTransferApplicationItems(item);
                    }
                    iExec.setHrTransferType(transfer.getHrTransferType());
                    iExec.setTransferApplicationItems(item);
                    iExec.setEffectiveDate(item.getEffectiveDate());
                    iExec.setEndDate(item.getEndDate());
                    iExec.setEffectiveDate(item.getEffectiveDate());
                    iExec.setTransferUid(item.getTransferUid());
                    iExec.setBranch(item.getBranch());
                    iExec.setJob(item.getJob());
                    iExec.setRankId(item.getRankId());
                    iExec.setOnDutyState(item.getOnDutyState());
                    iExec.setStaffShare(item.getStaffShare());
                    iExec.setWorkPost(item.getWorkPost());

                    if ((sType.equals("000102"))) {

                        iExec.setEffectiveDate(dToday);
                        //  当天前（包括当天）调动单明细
                        Date date = iExec.getTransferApplicationItems().getRepealDate();
                        if(iExec.getTransferApplicationItems().isIconExecute()){
                            //写入待调入数据 暂 默认不跨公司的
                            updateStaffing(item.getTransferUid().getCompany(), item.getBranchAfter(),item.getWorkPostAfter(), -1, 0,0);
                            //写入待调出数据
                            updateStaffing(item.getTransferUid().getCompany(), item.getBranch(),item.getWorkPost(),1,0,0);
                        } else  if(!iExec.getTransferApplicationItems().isIconExecute()){
                            //写入待调入数据 暂 默认不跨公司的
                            updateStaffing(item.getTransferUid().getCompany(), item.getBranchAfter(),item.getWorkPostAfter(), 0, -1,0);
                            //写入待调出数据
                            updateStaffing(item.getTransferUid().getCompany(), item.getBranch(),item.getWorkPost(),0,0,-1);
                        }


                        List<Staffing> listStaffing = staffingRepository.findByBranchAndWorkPost(item.getBranch(),item.getWorkPost());
                        //找招聘单
                        for (Staffing staffing: listStaffing ) {
                            List<RecruitOrder> recruitOrders = recruitOrderRepository.findByStaffingAndState(staffing, "approve");
                            recruitOrders.forEach(recruitOrder -> {

                                Set<Employee> employees = recruitOrder.getEmployeeSets();
                                employees.forEach(employee -> {
                                    if (employee == item.getTransferUid()) {
                                        employees.remove(employee);
                                        recruitOrder.setCurrentRecruitQty(recruitOrder.getCurrentRecruitQty() - 1);
                                    }
                                });
                            });
                        }
                        listEndExec.add(iExec);
                    }else if(sType.equals("000103")&& dToday.getTime() <= endDate.getTime() ){
                        // 结束日期 未到的支援单  执行 还原支援内容

                        iExec.setEndDate(dToday);
                        listEndExec.add(iExec);
                    }else {
                        throw new RuntimeException("已经超过可终止时间！");
                    }
                    item.setRepealUid(request.getPerson());
                    item.setRepeal(true);
                    executionRepository.saveAndFlush(iExec);
                }else if (!item.isRepeal()){
                    //未被终止的支援单最后支援结束时间
                    if(item.getEndDate()!=null){
                        item.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 23:59:59",DateUtil.SHOW_DATETIME_FORMAT));
                    }
                }

            }
        });


        if(listEndExec.size()>0) zzRYXX(listEndExec); // 同步更新终止列表
        //执行内容 END
        transfer.setLastUpdatedStamp(new Date());
        if(items.stream().allMatch(TransferApplicationItem::isRepeal)) transfer.setState("repeal");
        return transferApplicationRepository.saveAndFlush(transfer);
    }



    /**
     * 功能：过期"hr.transferApplication.findSupportApplication"  doneExpired (过期审核不生成执行表 审核时已生成过支援结束的执行表内容)
     * @param request
     */
    public TransferApplication doneExpired(SimpleRequest request) throws RuntimeException {
        TransferApplication transfer1 = request.getO(TransferApplication.class);
        TransferApplication transfer = transferApplicationRepository.findOne(transfer1.getId());
        //   只执行非今天前的
        List<TransferApplicationExecution> listExec = new ArrayList();// 执行 生效列表
        List<TransferApplicationExecution> listEndExec = new ArrayList(); // 终止支援列表

        Set<TransferApplicationItem> items = transfer.getTransferApplicationItems();

        //判断当前时间是上午还是下午 结果为“0”是上午 结果为“1”是下午
        GregorianCalendar ca = new GregorianCalendar();
        int i = ca.get(GregorianCalendar.AM_PM);
        String time = i == 0 ? "AM" :"PM";

        Enumeration hrTransferType = transfer.getHrTransferType();
        String sType = hrTransferType.getId();//类型(000102:hrTT_01调动; 000103:hrTT_02支援)
        items.forEach(item -> {
            Date dToday = new Date();
            Date startDate = item.getEffectiveDate();
            Date endDate = item.getEndDate();
            // 支援单增加上下午 需要重新计算准确上下午时间 12:00 23:59
            if(hrTransferType.getId().equals("000103")){
                //开始时间为上午 6:00 为下午12:00 结束时间为上午 12:00 下午为23:59:59
                if (item.getEffectiveTime().getCode().equals("AM")){
                    startDate = DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 06:00:00",DateUtil.SHOW_DATETIME_FORMAT);
                }
                if (item.getEffectiveTime().getCode().equals("PM")){
                    startDate = DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT);
                }
                if (item.getEndTime().getCode().equals("AM")){
                    endDate = DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT);
                }
                if (item.getEndTime().getCode().equals("PM")){
                    endDate = DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 23:59:59",DateUtil.SHOW_DATETIME_FORMAT);
                }
            }
            // 执行内容
            TransferApplicationExecution iExec = new TransferApplicationExecution();
            iExec.setHrTransferType(transfer.getHrTransferType());
            iExec.setTransferApplicationItems(item);
            iExec.setEffectiveDate(item.getEffectiveDate());
            iExec.setEndDate(item.getEndDate());
            iExec.setTransferUid(item.getTransferUid());
            iExec.setBranch(item.getBranchAfter());
            iExec.setJob(item.getJobAfter());
            iExec.setRankId(item.getRankIdAfter());
            iExec.setOnDutyState(item.getOnDutyStateAfter());
            iExec.setStaffShare(item.getStaffShareAfter());
            iExec.setWorkPost(item.getWorkPostAfter());
            if(!item.isIconExecute()){
                if ((dToday.getTime() > startDate.getTime()&&sType.equals("000102"))||(dToday.getTime() > startDate.getTime()&& dToday.getTime() < endDate.getTime() &&sType.equals("000103"))) {
                    //  当天前（包括当天）的调动单明细 或 今天前但结束日期未到当天（包括当天）的支援单  执行 调动支援内容
                    listExec.add(iExec);
                }else if(dToday.getTime() > startDate.getTime()&& dToday.getTime() > endDate.getTime() &&sType.equals("000103")){
                    //  当天前  结束日期 也过了当天的支援单  执行 还原支援内容
                    listEndExec.add(iExec);
                }else if(DateUtils.isSameDay(dToday, startDate) && sType.equals("000103")){
                    //今天的支援明细 当前时间是下午生效时间是下午，并且结束日期未到 执行支援内容
                    if(item.getEffectiveTime().getCode().equals("AM") && time.equals("PM") && dToday.getTime() < item.getEndDate().getTime()){
                        listExec.add(iExec);
                    }
                }else {
                    return;
                }
            }
        });
        if(listExec.size()>0)updateRYXX(listExec,true);//更新执行列表，是否扣减待调人数：扣(done时生成过执行表，有增加待调人数此处应扣回)
        if(listEndExec.size()>0) zzRYXX(listEndExec); // 同步更新终止列表
        //执行内容 END
        transfer.setLastUpdatedStamp(new Date());
        TransferApplication transfers = transferApplicationRepository.saveAndFlush(transfer);
        return transfers;
    }

    /**
     * 功能：执行表
     */
    private void insertExecution(TransferApplicationItem item,Enumeration hrTransferType) {
        TransferApplicationExecution iExec = new TransferApplicationExecution();
        iExec.setHrTransferType(hrTransferType);
        iExec.setTransferApplicationItems(item);
        iExec.setEffectiveDate(item.getEffectiveDate());
        iExec.setEndDate(item.getEndDate());
        // 支援单增加上下午 需要重新计算准确上下午时间 12:00 23:59
        if(hrTransferType.getId().equals("000103")){
            //开始时间为上午 6:00 为下午12:00 结束时间为上午 12:00 下午为23:59:59
            if (item.getEffectiveTime().getCode().equals("AM")){
                iExec.setEffectiveDate(DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 06:00:00",DateUtil.SHOW_DATETIME_FORMAT));
            }
            if (item.getEffectiveTime().getCode().equals("PM")){
                iExec.setEffectiveDate(DateUtil.parse( DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
            }
            if (item.getEndTime().getCode().equals("AM")){
                iExec.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
            }
            if (item.getEndTime().getCode().equals("PM")){
                iExec.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 23:59:59",DateUtil.SHOW_DATETIME_FORMAT));
            }
        }
        iExec.setTransferUid(item.getTransferUid());
        iExec.setBranch(item.getBranchAfter());
        iExec.setJob(item.getJobAfter());
        iExec.setRankId(item.getRankIdAfter());
        iExec.setOnDutyState(item.getOnDutyStateAfter());
        iExec.setStaffShare(item.getStaffShareAfter());
        iExec.setWorkPost(item.getWorkPostAfter());
        if(hrTransferType.getId().equals("000102")){//调动 才对编制才修改
            //写入待调入数据 暂 默认不跨公司的
            updateStaffing(item.getTransferUid().getCompany(), item.getBranchAfter(),item.getWorkPostAfter(), 0, 1,0);
            //写入待调出数据
            updateStaffing(item.getTransferUid().getCompany(), item.getBranch(),item.getWorkPost(), 0, 0,1);
        }
        executionRepository.saveAndFlush(iExec);
    }

    /**
     * 功能：执行使用
     * @param
     * @return
     */
    private static Date getNextDate(Date date,int num) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, +num); //今天的时间加一天
        date = calendar.getTime();
        return date;
    }

    public void updateRYQX(SimpleRequest simpleRequest) throws RuntimeException {
        Date dDate = new Date(); //  定时任务应该没带 日期

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date dToday= formatter.parse(formatter.format(dDate),new ParsePosition(0));

        String sTomorrow = formatter.format(getNextDate(dDate,1));//明天
        Date dTomorrow= formatter.parse(sTomorrow,new ParsePosition(0));

        String sYesterday = formatter.format(getNextDate(dDate,-1));//昨天
        Date dYesterday = formatter.parse(sYesterday,new ParsePosition(0));

        // 终止 支援
        List<TransferApplicationExecution> listEnd = executionRepository.findByEndDate((Date) dYesterday,(Date) dToday);
        if(listEnd.size()>0){
            zzRYXX(listEnd);
            //更新主表时间戳，App拉取
            listEnd.forEach(itemExec -> {
                TransferApplicationItem item = transferApplicationItemRepository.findOne(itemExec.getTransferApplicationItems().getId());
                TransferApplication transferApplication = item.getTransferApplications();
                transferApplication.setLastUpdatedStamp(new Date());
                transferApplicationRepository.saveAndFlush(transferApplication);
            });
        }

        // 执行 生效(未执行 未终止的调动支援单)
        List<TransferApplicationExecution> listExec = executionRepository.findByEffectiveDate((Date) dYesterday,(Date) dTomorrow)
                .stream().filter(excution ->!excution.getTransferApplicationItems().isRepeal()&&!excution.getTransferApplicationItems().isIconExecute() )
                .collect(Collectors.toList());
        if(listExec.size()>0){
            updateRYXX(listExec, true); //（参数：执行列表, true 将 生效执行表时 待调出入数据 扣减）
            listExec.forEach(itemExec->{
                TransferApplicationItem item = transferApplicationItemRepository.findOne(itemExec.getTransferApplicationItems().getId());
                TransferApplication transferApplication = item.getTransferApplications();
                transferApplication.setLastUpdatedStamp(new Date());
                transferApplicationRepository.saveAndFlush(transferApplication);
            });
        }
    }

    /**
     * 定时任务终止 支援
     * @param request
     * @throws RuntimeException
     */
    public void repealRYXX(SimpleRequest request) throws RuntimeException{
        Date dDate = new Date(); //  定时任务应该没带 日期

        //判断当前时间是上午还是下午 结果为“0”是上午 结果为“1”是下午
        GregorianCalendar ca = new GregorianCalendar();
        int i = ca.get(GregorianCalendar.AM_PM);
        String time = i == 0 ? "AM" :"PM";

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        Date dToday= formatter.parse(formatter.format(dDate),new ParsePosition(0));

        String sYesterday = formatter.format(getNextDate(dDate,-1));//昨天
        Date dYesterday = formatter.parse(sYesterday,new ParsePosition(0));

        // 终止 支援
        List<TransferApplicationExecution> listEnd = new ArrayList<>();

        if(time.equals("AM")){
            listEnd = executionRepository.findByEndDate((Date) dYesterday,(Date) dToday);
        }else if(time.equals("PM")){
            listEnd = executionRepository.findByEndDate(dToday,DateUtil.parse(DateUtil.format(dToday,DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
        }

        if(listEnd.size()>0){
            zzRYXX(listEnd);
            //更新主表时间戳，App拉取
            listEnd.forEach(itemExec -> {
                TransferApplicationItem item = transferApplicationItemRepository.findOne(itemExec.getTransferApplicationItems().getId());
                TransferApplication transferApplication = item.getTransferApplications();
                transferApplication.setLastUpdatedStamp(new Date());
                transferApplicationRepository.saveAndFlush(transferApplication);
            });
        }
    }

    /***
     * 定时任务执行调动支援单
     * @param request
     * @throws RuntimeException
     */
    public void executedRYXX(SimpleRequest request) throws RuntimeException{
        Date dDate = new Date(); //  定时任务应该没带 日期
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

        //判断当前时间是上午还是下午 结果为“0”是上午 结果为“1”是下午
        GregorianCalendar ca = new GregorianCalendar();
        int i = ca.get(GregorianCalendar.AM_PM);
        String time = i == 0 ? "AM" :"PM";

        String sTomorrow = formatter.format(getNextDate(dDate,1));//明天
        Date dTomorrow= formatter.parse(sTomorrow,new ParsePosition(0));

        Date dToday= formatter.parse(formatter.format(dDate),new ParsePosition(0));

        String sYesterday = formatter.format(getNextDate(dDate,-1));//昨天
        Date dYesterday = formatter.parse(sYesterday,new ParsePosition(0));

        List<TransferApplicationExecution> listExec = new ArrayList<>();
        //如果是上午 说明是凌晨的定时任务
        if (time.equals("AM")){
            // 执行 生效(未执行 未终止的调动支援单)
            // 凌晨的定时任务只执行当天上午生效的支援单
            listExec = executionRepository.findByEffectiveDate(dYesterday,
                    DateUtil.parse(DateUtil.format(dToday,DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT))
                    .stream().filter(excution ->!excution.getTransferApplicationItems().isRepeal()&&!excution.getTransferApplicationItems().isIconExecute() )
                    .collect(Collectors.toList());
        }else if(time.equals("PM")){
            //下午的定时任务只执行当天的单
            listExec = executionRepository.findByEffectiveDateTodayNoon(dToday,DateUtil.parse
                    (DateUtil.format(dToday,DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT))
                    .stream().filter(excution ->!excution.getTransferApplicationItems().isRepeal()&&!excution.getTransferApplicationItems().isIconExecute() )
                    .collect(Collectors.toList());
        }

        if(listExec.size()>0){
            updateRYXX(listExec, true); //（参数：执行列表, true 将 生效执行表时 待调出入数据 扣减）
            listExec.forEach(itemExec->{
                TransferApplicationItem item = transferApplicationItemRepository.findOne(itemExec.getTransferApplicationItems().getId());
                TransferApplication transferApplication = item.getTransferApplications();
                transferApplication.setLastUpdatedStamp(new Date());
                transferApplicationRepository.saveAndFlush(transferApplication);
            });
        }

    }

    /**
     * 功能：执行  生效
     * @param
     * @return
     */
    private void updateRYXX(List<TransferApplicationExecution> listExec,Boolean transferFlag) throws RuntimeException {
        JSONArray synPersonList = new JSONArray();  // 同步旧框架 使用
        listExec.forEach(itemExec -> {
            Enumeration hrTransferType = itemExec.getHrTransferType();
            String sType = hrTransferType.getId();
            JSONObject synPerson = new JSONObject();  // 同步旧框架 使用
            synPerson = updateEmployee(sType,itemExec,synPerson,transferFlag);
            //推送钉钉调动同步群组
            SpringManager.getBean(OutboxSubscriberService.class)
                    .commonSendRequest("local:hrDingDingDeptService.transferDingDing",
                            "transferDingDing" + new Date().getTime() , new JSONObject(MapUtil.mapper(
                                    "id", itemExec.getTransferApplicationItems().getId()
                            )));

            try {
                synPerson = updatePosts(itemExec, synPerson);
            } catch (Exception e) {
                throw new RuntimeException();
            }
            synPersonList.add(synPerson); // 同步旧框架 使用
        });
    }

    private Map<String, Object> checkSup(TransferApplicationItem item,int repeal) throws RuntimeException{
        Map sup = new HashMap();
        sup.put("document_type","000103");//单据类型
        sup.put("support_number",item.getTransferApplications().getId());//支援单编码
        sup.put("employee_code",item.getTransferUid().getOrigin());//人员编码
        sup.put("branch",item.getBranch().getOrigin());//部门

        sup.put("branch_after",item.getBranchAfter().getOrigin());//	调动后部门
        sup.put("job",item.getJob().getId());//职位
        sup.put("job_after",item.getJobAfter().getId());//调动后职位
        sup.put("post",item.getWorkPost().getId());//岗位
        sup.put("post_after",item.getWorkPostAfter().getId());//调动后岗位
        sup.put("rank",item.getRankId().getId());//职级
        sup.put("rank_after",item.getRankIdAfter().getId());//调动后职级
        sup.put("duty_status",item.getOnDutyState().getId());//在岗状态
        sup.put("duty_status_after",item.getOnDutyStateAfter().getId());//调动后在岗状态
        sup.put("staff",item.getStaffShare());//份数
        sup.put("staff_after",item.getStaffShareAfter());//调动后份数
        if (item.isDriver()){
            sup.put("is_driver","1");//是否准驾
        }else {
            sup.put("is_driver","0");//是否准驾
        }
        if (item.isEchelon()){
            sup.put("is_echelon","1");//是否梯队
        }else {
            sup.put("is_echelon","0");//是否梯队
        }
        sup.put("transfer_type",item.getHrTransferKind().getId());//调动性质
        sup.put("handover_date",DateUtil.format(item.getHandoverDate(),DateUtil.SHOW_DATE_FORMAT));//交换日期
        sup.put("effective_date",DateUtil.format(item.getEffectiveDate(),DateUtil.SHOW_DATE_FORMAT));//生效日期
        sup.put("end_date",DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT));//支援结束日期
        if (item.getRoleList()!=null){
            sup.put("role_list",item.getRoleList());//本地角色备份
        }else {
            sup.put("role_list","");//本地角色备份
        }
        sup.put("is_effective","1");//是否已执行
        if (item.getUpdateDate()!=null){
            sup.put("edit_date",DateUtil.format(item.getUpdateDate(),DateUtil.SHOW_DATE_FORMAT));//编辑日期
        } else {
            sup.put("edit_date","");//编辑日期
        }
        SimpleDateFormat bartDateFormat = new SimpleDateFormat("yyyyMMdd.hhmmss.SSS");
        sup.put("timestamp",bartDateFormat.format(item.getLastUpdatedStamp()));//时间戳
        sup.put("is_closed",repeal);//是否终止
        sup.put("document_number",String.valueOf(item.getId()));//明细表编码
        if (item.isDistribution()){
            sup.put("is_distribution","1");
        }else {
            sup.put("is_distribution","0");//是否分配跟踪任务
        }
        return sup;
    }
    // 更新 人员信息表  (执行类型，执行表数据，更新人员，是否扣减待调数据：是 -1)
    private JSONObject updateEmployee(String sType, TransferApplicationExecution itemExec, JSONObject synPerson, Boolean transferFlag) throws RuntimeException{
        String employeeId = itemExec.getTransferUid().getId();  //人员编码
        List<Employee> person = employeeRepository.findAllById((String)employeeId);
        Employee upPerson = person.get(0); //支援不修改人员档案
        TransferApplicationItem item = itemExec.getTransferApplicationItems();
        if(!item.isIconExecute()){ // 未执行的才执行 防止 其他途径执行过对编制 有影响
            if(sType.equals("000102")){//调动 类型 才对  编制作修改
                //更新编制
                int iTransferInQty =0;
                int iTransferOutQty =0;
                int iRealQtyIn = 1;
                int iRealQtyOut = -1;
                if(item.getBranch()!=item.getBranchAfter() && item.getWorkPost()!=item.getWorkPostAfter()){
                    upPerson.setTransferBranchDate(item.getEffectiveDate());
                    upPerson.setTransferPostDate(item.getEffectiveDate());
                    upPerson.setTransferBranchAndPostDate(item.getEffectiveDate());
                } else if (item.getBranch()==item.getBranchAfter() && item.getWorkPost()!=item.getWorkPostAfter()){
                    upPerson.setTransferPostDate(item.getEffectiveDate());
                    upPerson.setTransferBranchAndPostDate(item.getEffectiveDate());
                } else if (item.getBranch()!=item.getBranchAfter() && item.getWorkPost()==item.getWorkPostAfter()){
                    upPerson.setTransferBranchDate(item.getEffectiveDate());
                    upPerson.setTransferBranchAndPostDate(item.getEffectiveDate());
                }
                upPerson.setRank(itemExec.getRankId());
                upPerson.setOnDutyState(itemExec.getOnDutyState());
                upPerson.setStaffShare(itemExec.getStaffShare());
                // 岗位 职位 部门 作修改
                upPerson.setWorkBranch(itemExec.getBranch());
                upPerson.setJob(itemExec.getJob());
                upPerson.setPost(itemExec.getWorkPost());
                upPerson.setStaffShare(itemExec.getStaffShare());
                upPerson.setCompany(item.getCompanyAfter());
                if(transferFlag==true){ // 点击审核时(没增加的待调动 人数) 在此不扣减
                    iTransferInQty = -1;
                    iTransferOutQty = -1;
                }
                // 更新 待调入
                updateStaffing(upPerson.getCompany(), itemExec.getBranch(), itemExec.getWorkPost(), iRealQtyIn, iTransferInQty, 0);
                // 更新 待调出
                updateStaffing(upPerson.getCompany(), itemExec.getTransferApplicationItems().getBranch(), itemExec.getTransferApplicationItems().getWorkPost(), iRealQtyOut, 0, iTransferOutQty);
                //更新 调动记录
                updateTransferRecord(item);
            }

        }
        saveHRLog("员工： " + upPerson.getName() +upPerson.toString());
        employeeService.createAndUpdate(upPerson);
        item.setIconExecute(true);
        // 同步旧框架 使用  get外部ID即旧框架使用ID
        return synPersonHandle(employeeId,itemExec,synPerson);
        // 同步旧框架 使用 END
    }



    // 同步数据 处理
    private JSONObject synPersonHandle(String employeeId,TransferApplicationExecution itemExec,JSONObject synPerson) throws RuntimeException{
        TransferApplicationItem item = itemExec.getTransferApplicationItems();
        if (itemExec.getHrTransferType().getId().equals("000102")){
            synPerson.put("ZW",itemExec.getJob().getOrigin());//
            synPerson.put("Branch",itemExec.getBranch().getOrigin());//
            synPerson.put("GW",itemExec.getWorkPost().getName());//岗位名称
            synPerson.put("GWID",itemExec.getWorkPost().getId());// 新旧系统 编码 将一致
            synPerson.put("ZWJB",itemExec.getRankId().getName());
            synPerson.put("FS",itemExec.getStaffShare());
        } else {
            synPerson.put("ZW",item.getJob().getOrigin());//
            synPerson.put("Branch",item.getBranch().getOrigin());//
            synPerson.put("GW",itemExec.getWorkPost().getName());//岗位名称
            synPerson.put("GWID",item.getWorkPost().getId());// 新旧系统 编码 将一致
            synPerson.put("ZWJB",item.getRankId().getName());
            synPerson.put("FS",item.getStaffShare());
        }
        synPerson.put("EmployeeId",employeeId);
        String sYGDAH = "";
        if(itemExec.getOnDutyState()!=null){
            String sOnDutyState =itemExec.getOnDutyState().getId();
            String supTopic = "event:hr.hrTransferSyn.checkZGZT";
            sYGDAH = (String) EventUtil.sendSynEvent(this, supTopic, sOnDutyState).stream().findFirst().get();
        }
        synPerson.put("YGDAH",sYGDAH);


        String sRYLX = ""; // RYLX	NUMBER(2)	人员类型(0:行政人员\仓管\收款员;1:采购业务员;2:销售业务员)
        if(itemExec.getBranch().getBranchType().getId().equals("000006")){ // 采购
            sRYLX = "1";
        }else if(itemExec.getBranch().getBranchType().getId().equals("000007")){ // 销售
            sRYLX = "2";
        }else {
            sRYLX = "0";
        }
        synPerson.put("RYLX",sRYLX);
        String sRYID= itemExec.getTransferUid().getOrigin(); // 外部编码 即 原旧框架 人员ID
        if(sRYID!=null){
            synPerson.put("RYID",sRYID);
        }else{
            synPerson.put("RYID",itemExec.getTransferUid().getId());
        }
        synPerson.put("RYMC",itemExec.getTransferUid().getName());
        return synPerson;
    }
    // 更新 岗位(角色)
    private JSONObject updatePosts(TransferApplicationExecution itemExec,JSONObject synPerson) throws Exception {
        Set<TransferApplicationRole> roleList = itemExec.getTransferApplicationItems().getTransferApplicationRoles();
        StringBuffer sRoleList = new StringBuffer();  // 同步旧框架 使用
        List<String> orginList = new ArrayList<>();
        if(roleList!=null&&roleList.size()>0) {
            //查找 用户
            String sOrigin = itemExec.getTransferUid().getOrigin();
            try{
                User user = userRepository.findByOrigin(sOrigin);
                if(user!=null){
                    // 更新要备份 的 原 item 角色 列表
                    List<Post> postLists = user.getPosts();
                    if (postLists.size()>0) {
                        List<Post> posts = new ArrayList<>();
                        StringBuffer yRoleList = new StringBuffer();
                        postLists.forEach(yRole -> {
                            yRoleList.append(yRole.getId()+";");

                        });
                        itemService.updateItem(itemExec,yRoleList.toString());
                    }
                    // 更新 原 item 角色 列表
                    Integer iBid  = user.getId(); //user编码
                    List<Post> posts = new ArrayList<>();
                    roleList.forEach(role -> {
                        String sAid = role.getPostId();
                        Post oldPost = postRepository.findOne(sAid);
                        orginList.add(oldPost.getOrigin());
//                        sRoleList.append(oldPost.getOrigin()+";");  // 同步旧框架 使用
                        Post post = postRepository.findOne(sAid);
                        posts.add(post);
                    });
                    orginList.stream().distinct().forEach(orgin -> {
                        sRoleList.append(orgin+";");  // 同步旧框架 使用
                    });
                    user.setPosts(posts); // 创建到中间表
                    userRepository.saveAndFlush(user);
                } else{
                    // 没有 操作员的创建
                    SimpleRequest request = new SimpleRequest();
                    User newUser = new User();
                    newUser.setName(itemExec.getTransferUid().getName());
                    newUser.setOrigin(itemExec.getTransferUid().getOrigin());
                    List postLists = new JSONArray();
                    roleList.forEach(role -> {
                        String sAid = role.getPostId();
                        Post oldPost = postRepository.findOne(sAid);
                        orginList.add(oldPost.getOrigin());
                        JSONObject post = new JSONObject();
                        post.put("id",role.getPostId());
                        postLists.add(post);  //
                    });
                    orginList.stream().distinct().forEach(orgin -> {
                        sRoleList.append(orgin+";");  // 同步旧框架 使用
                    });
                    newUser.setPostLits(postLists);
                    request.setData(newUser);
                    userService.save(request);
                }
            }catch(Exception e){
                throw new RuntimeException("更新岗位出错！");
            }
        }
        // 同步旧框架 使用
        synPerson.put("Roles",sRoleList);
        return synPerson;
        // 同步旧框架 使用 END
    }


    // 终止
    private void zzRYXX(List<TransferApplicationExecution> listEnd) throws RuntimeException {
        JSONArray synPersonList = new JSONArray();  // 同步旧框架 使用
        // 获取有效 要终止 列表
        listEnd.forEach(itemzz -> {

            JSONObject synPerson = new JSONObject();
            String employeeId  = itemzz.getTransferUid().getId(); // 人员编码
            List<Employee> person = employeeRepository.findAllById(employeeId);
            int yItemId = itemzz.getTransferApplicationItems().getId();
            List<TransferApplicationItem> item = itemService.findById(yItemId);
            TransferApplicationItem yItem = item.get(0);
            if(yItem.getTransferApplications().getHrTransferType().getDescription().equals("调动")){
                Employee upPerson = person.get(0);
                upPerson.setWorkBranch(yItem.getBranch());
                upPerson.setJob(yItem.getJob());
                upPerson.setRank(yItem.getRankId());
                upPerson.setOnDutyState(yItem.getOnDutyState());
                upPerson.setStaffShare(yItem.getStaffShare());
                upPerson.setPost(yItem.getWorkPost());
                upPerson.setCompany(yItem.getCompany());
                employeeService.createAndUpdate(upPerson);
                // 将调动记录单删除
                transferRecordValid(itemzz);
            }

            //推送钉钉终止操作更新钉钉群组
            SpringManager.getBean(OutboxSubscriberService.class)
                    .commonSendRequest("local:hrDingDingDeptService.restoreDingDing",
                            "restoreDingDing" + new Date().getTime() ,
                            new JSONObject(MapUtil.mapper(
                                    "id", itemzz.getTransferApplicationItems().getId()
                            )));
            // 还原 支援时 前 的角色
            String sJsList = yItem.getRoleList();
            User user = userRepository.findByOrigin(yItem.getTransferUid().getOrigin());
            if (user!=null){
                if(sJsList!=null ) {
                    String sRoles = updateUser(user, sJsList);
                    synPerson.put("Roles", sRoles);
                } else {
                    user.setPosts(null);
                    synPerson.put("Roles", null);
                }
                userRepository.saveAndFlush(user);
            }

            itemService.updateItemIconExecute(yItem); //终止更新执行标识
        });
    }
    // 更新用户岗位
    private String updateUser(User user,String sJsList){
        Integer iBid  = user.getId(); //user编码
        List<Post> posts = new ArrayList<>();
        StringBuffer sRoleList = new StringBuffer();
        String[] sJS = sJsList.toString().split(";");
        for (int f = 0, iLen = sJS.length; f < iLen; f++) {
            String ryjs = sJS[f];
            Post post = postRepository.findOne(ryjs);
            if(post != null ) {
                sRoleList.append(post.getOrigin()+";");  // 同步旧框架 使用
                posts.add(post);
            }

        }
        user.setPosts(posts); // 创建到中间表
        return sRoleList.toString();
    }



    /**
     * 功能：查找选择人员的所有岗位(角色)
     * @param
     */
    public List qryEmployeePosts(SimpleRequest request)throws Exception {
        Integer sPerson =request.get("employeeNumber");
        List<Map> roleList = transferApplicationRepository.qryEmployeePosts(sPerson);
        if (roleList.size()>0){
            return roleList;
        }else {
            return null;
        }
    }

    /**
     * 功能：更新 编制 信息
     * @param
     */
    private void updateStaffing(PartyRole company, Branch branch, WorkPost workPost, int iRealQtyAdd, int iTransferInQty, int iTransferOutQty)throws RuntimeException {
        // 更新 编制 如无 增（一般情况不会无）
        List<Staffing> listStaffing = staffingRepository.findByBranchAndWorkPost(branch, workPost);
        Staffing staffing = new Staffing();
        int realQty = 0;
        int transferInQty = 0;
        int transferOutQty = 0;
        if (listStaffing.size() > 0) {
            staffing = listStaffing.get(0);
            realQty = staffing.getRealQty();
            transferInQty = staffing.getTransferInQty();
            transferOutQty = staffing.getTransferOutQty();
        } else {
            staffing.setCompany(company);
            staffing.setBranch(branch);
            staffing.setWorkPost(workPost);
        }
        realQty = realQty+ iRealQtyAdd;
        transferInQty = transferInQty + iTransferInQty;
        transferOutQty = transferOutQty + iTransferOutQty;
        staffing.setRealQty(realQty);
        staffing.setTransferInQty(transferInQty);
        staffing.setTransferOutQty(transferOutQty);
        staffingService.create(staffing);
    }

    public int findTransferNum(SimpleRequest request){
        String transferUid = request.get("transferUid");
        Date today = new Date();
        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(today);//把当前时间赋给日历
        calendar.add(calendar.MONTH, -3); //设置为前3月
        Date dBefore = calendar.getTime(); //得到前3月的时间
        return transferApplicationRepository.findTransferNum(transferUid,today,dBefore);
    }

    //更新调动记录
    public void updateTransferRecord(TransferApplicationItem item){
        Employee employee = item.getTransferUid();
        Date date = item.getEffectiveDate();
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, -1);//-1今天的时间加一天
        date = calendar.getTime();
        //将上一个调动记录的调离时间写上
        List<TransferRecord> transferRecords = transferRecordRepository.findByEmployee(employee);
        if (!transferRecords.isEmpty()){
            TransferRecord oldTransferRecord = transferRecords.get(transferRecords.size()-1);
            oldTransferRecord.setTransferOut(date);
            transferRecordRepository.saveAndFlush(oldTransferRecord);
        }
        TransferRecord transferRecord = new TransferRecord();
        transferRecord.setEmployee(employee);
        transferRecord.setWorkBranch(item.getBranchAfter());
        transferRecord.setPost(item.getWorkPostAfter());
        transferRecord.setJob(item.getJobAfter());
        transferRecord.setRank(item.getRankIdAfter());
        transferRecord.setOnDutyState(item.getOnDutyStateAfter());
        transferRecord.setTransferOn(item.getEffectiveDate());
        transferRecord.setEchelon(item.isEchelon());
        transferRecord.setDriver(item.isDriver());
        transferRecord.setValid(true);
        transferRecord.setTransferApplicationItemId(String.valueOf(item.getId()));
        transferRecordRepository.saveAndFlush(transferRecord);
        List<TransferRecord> transferRecordList = transferRecordRepository.findByEmployee(employee);
        TransferRecord oldTransferRecord = transferRecordList.get(transferRecordList.size()-1);
        oldTransferRecord.setOldTransferApplicationItemId(String.valueOf(item.getId()));
        transferRecordRepository.saveAndFlush(oldTransferRecord);
    }

    //终止时将之前记录的调动记录单标记为无效 并且将前一张记录单的调离时间清空
    public void transferRecordValid(TransferApplicationExecution execution){
        TransferApplicationItem item = execution.getTransferApplicationItems();
        if(item.getTransferApplications().getHrTransferType().getId().equals("000102")){
            Employee employee = item.getTransferUid();
            List<TransferRecord> transferRecords = transferRecordRepository.findByEmployee(employee).stream().sorted(Comparator.comparing(TransferRecord::getTransferOn)).collect(Collectors.toList());//根据调入时间自然顺序
            if (!transferRecords.isEmpty()){
                TransferRecord oldTransferRecord = transferRecords.get(transferRecords.size()-1);
                TransferRecord oldItemTransferRecord = transferRecordRepository.findByOldTransferApplicationItemId(String.valueOf(item.getId()));

                oldTransferRecord.setTransferOut(new Date());
                transferRecordRepository.saveAndFlush(oldTransferRecord);

                // 终止调动后 写入新的调动记录
                TransferRecord transferRecord = new TransferRecord();
                transferRecord.setEmployee(employee);
                transferRecord.setWorkBranch(item.getBranch());
                transferRecord.setPost(item.getWorkPost());
                transferRecord.setJob(item.getJob());
                transferRecord.setRank(item.getRankId());
                transferRecord.setOnDutyState(item.getOnDutyState());
                transferRecord.setTransferOn(new Date());
                transferRecord.setEchelon(item.isEchelon());
                transferRecord.setDriver(item.isDriver());
                transferRecord.setValid(true);
                transferRecord.setTransferApplicationItemId(String.valueOf(item.getId()));
                transferRecordRepository.saveAndFlush(transferRecord);


            }

        }

    }
    /**
     * 传入的时间加一天
     * @param date
     * @return
     */
    private Date dateAdd(Date date,int i){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, i);//+1今天的时间加一天
        return calendar.getTime();
    }

    /**
     * 支援单审核之后由于业务需要临时变动支援结束日期
     * @param request
     * @return
     */
    public TransferApplication adjust(SimpleRequest request){
        TransferApplication transferApplication = request.getO(TransferApplication.class);
        transferApplication.getTransferApplicationItems().stream().forEach(item -> {
            TransferApplicationExecution execution = executionRepository.findByTransferApplicationItems(item);
            if(execution!=null){
                //调动单直接修改日期
                if(transferApplication.getHrTransferType().getId().equals("000102")){
                    execution.setEndDate(item.getEndDate());
                }else {
                    //支援单
                    // 结束时间为上午 12:00 下午为23:59:59
                    if (item.getEndTime().getCode().equals("AM")){
                        execution.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 12:00:00",DateUtil.SHOW_DATETIME_FORMAT));
                    }
                    if (item.getEndTime().getCode().equals("PM")){
                        execution.setEndDate(DateUtil.parse( DateUtil.format(item.getEndDate(),DateUtil.SHOW_DATE_FORMAT)+" 23:59:59",DateUtil.SHOW_DATETIME_FORMAT));
                    }
                }
                executionRepository.save(execution);
            }
        });
        return transferApplicationRepository.saveAndFlush(transferApplication);
    }

    /**
     * 查询支援七天以上申请单
     * @param request
     * @return
     * @throws Exception
     */
    public com.apestech.framework.json.JSONObject transferApplicationToSup(SimpleRequest request) throws Exception {
        JSONObject jo = request.getJO();
        JSONArray condition = jo.getJSONArray("condition");
        if (condition != null) {
            for (int i = 0; i < condition.size(); i++) {
                if ("SUPPORT_PERIOD".equals(condition.getJSONObject(i).getString("field"))){
                    JSONObject json = new JSONObject();
                    if("GTE".equals(condition.getJSONObject(i).getString("operator"))){
                         json.put("field","EFFECTIVE_DATE");
                         json.put("operator","GTE");
                         json.put("value",condition.getJSONObject(i).getString("value"));
                         json.put("type","date");
                         condition.add(json);
                    }else if("LTE".equals(condition.getJSONObject(i).getString("operator"))){
                        json.put("field","TIME_END_DATE");
                        json.put("operator","LTE");
                        json.put("value",condition.getJSONObject(i).getString("value"));
                        json.put("type","date");
                        condition.add(json);
                    }
                }
            }
            jo.put("condition", condition);
        }
        return com.apestech.framework.json.JSON.toJSON(jo.toJSONString());
    }

    private void saveHRLog(String payload) {
        Document document = new Document();
        document.put("payload", payload);
        document.put("date", LocalDateTime.now());
        mongoTemplate.getCollection("hrConnection").insertOne(document);
    }

}
